; (function ($, Vue) {

  $.fn.vueTable = function (options) {
    // 缓存初始的配置
    const cusColumns = deepClone(options.columns);
    cusColumns.forEach((item, index) => initDefaultValue(item, index, cusColumns.length));
    const cacheKey = 'table-' + options.id;
    let useCache = false;
    let cacheOptions = getCache(cacheKey);
    if (options.version == cacheOptions.version) {
      Object.assign(options, cacheOptions)
      useCache = true;
    }
    let {
      rowKey,
      paging,
      pageSize,
      columns,
      params,
      url,
      method,
      beforeRender
    } = options;
    rowKey = rowKey || 'guid';
    paging = paging == undefined ? true : paging;
    const pageNumber = 1;
    const $el = this;
    // 处理用户传进来的配置
    const columnMap = {};
    const columnOrders = [];
    let selectionExtendHtml = '';
    // 计算宽度
    if (!useCache) {
      columns.forEach((item, index) => {
        initDefaultValue(item, index, columns.length);
        if (item.type == 'selection') {
          selectionExtendHtml = item.selectionExtendHtml;
          delete item.selectionExtendHtml;
        }
        columnMap[index] = item;
        columnOrders.push(index);
      })
      calcWidth($el, columns);
    } else {
      let obj;
      columns.forEach(item => {
        obj = {};
        Object.assign(obj, cusColumns[item.$index], item);
        Object.assign(item, obj);
        columnMap[item.$index] = item;
        columnOrders.push(item.$index);
        if (item.type == 'selection') {
          selectionExtendHtml = cusColumns[item.$index].selectionExtendHtml;
        }
      })
    }
    calcWidth($el, cusColumns);
    setCache(cacheKey, options);

    // 搜索
    function getTableData(condition = {}) {
      console.log('请求数据');
      vm.$refs.vueTable.loading = true;
      const param = ((params instanceof Function) ? params() : {}) || {};
      Object.assign(param, condition);
      $.ajax({
        url,
        type: method || 'GET',
        data: param,
        dataType: 'json',
        success: function (res) {
          const result = beforeRender(res);
          result.tableData.forEach((item, index) => {
            item.$index = item[rowKey] || index + (condition.pageNumber - 1) * condition.pageSize;
          });
          vm.$refs.vueTable.paramList = result.tableData;
          vm.$refs.vueTable.pageData.totality = result.total;
          vm.$refs.vueTable.checkBtnHtml = (selectionExtendHtml instanceof Function ? selectionExtendHtml(param) : selectionExtendHtml) || '';
          vm.$nextTick(() => {
            let moreList = $(vm.$el).find('.a_position_box');
            if (moreList.length) {
              moreList.remove();
              $('body').append(moreList);
            } else {
              return;
            }
            let timer = -1;
            moreList.mouseleave(function () {
              $(this).fadeOut();
            })
            moreList.mouseenter(function () {
              clearTimeout(timer);
            })
            // 操作--更多改变定位
            $(vm.$el).find('.toolsCls').mouseenter(function (e) {
              let _index = $(this).parents('tr').index();
              const nodeRect = this.getBoundingClientRect();
              moreList[_index].style.top = nodeRect.top + nodeRect.height + 'px';
              moreList[_index].style.left = nodeRect.left + 'px';
              moreList[_index].style.position = 'fixed';
              moreList[_index].style.zIndex = 10;
              moreList.eq(_index).fadeIn();
              moreList.eq(_index).mouseleave(function () {
                moreList.eq(_index).fadeOut();
              })
            });
            $(vm.$el).find('.toolsCls').mouseleave(function () {
              let _index = $(this).parents('tr').index();
              timer = setTimeout(() => {
                moreList.eq(_index).fadeOut();
              }, 100);
            })
          })
        },
        complete: function () {
          vm.$refs.vueTable.loading = false;
          if (wdb) {
            wdb.setJSON(md5(window.location.href), param);
          }
        }
      })
    }

    // 创建vue实例
    const vm = new Vue({
      el: $el[0],
      methods: {
        update() {
          this.$refs.vueTable.update();
        },
        getData() {
          return deepClone(this.$refs.vueTable.paramList);
        },
        search(params = {}) {
          params.pageNumber = params.pageNumber || 1;
          params.pageSize = this.$refs.vueTable.pageData.pageSize || 1;
          getTableData(params);
        },
        refresh() {
          this.$refs.vueTable.getTableList();
        },
        getSelectRows() {
          return this.$refs.vueTable.selectRows;
        }
      },
      mounted() {
        this.$refs.vueTable.clientWidth = $el.width();
        this.$refs.vueTable.paging = paging;
        this.$refs.vueTable.configDatas = columnMap;
        this.$refs.vueTable.configDataOrders = columnOrders;
        this.$refs.vueTable.modalData = {
          cusColumns,
          columns
        }
        this.$refs.vueTable.setModalData();
        this.$refs.vueTable.getTableData = getTableData;
        this.$refs.vueTable.cacheKey = cacheKey;
        this.$refs.vueTable.options = options;
        this.$refs.vueTable.setCache = setCache;
        // 设置页码
        this.$refs.vueTable.pageData.pageSize = pageSize || this.$refs.vueTable.pageData.pageSize;
      }
    })

    return {
      update: vm.update,
      getData: vm.getData,
      search: vm.search,
      refresh: vm.refresh,
      getSelectRows: vm.getSelectRows
    }
  }

  // 得到缓存
  function getCache(key) {
    let cache = localStorage.getItem(key);
    try {
      cache = JSON.parse(cache) || {};
    } catch (e) {
      cache = {}
    }
    return cache;
  }

  // 设置缓存
  function setCache(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  }

  // 判断arr是否为一个数组，返回一个bool值
  function isArray(arr) {
    return Object.prototype.toString.call(arr) === '[object Array]';
  }

  // 初始化默认值
  function initDefaultValue(item, index, length) {
    item.$index = index;
    item.fixable = item.fixable == undefined ? true : !!item.fixable;
    item.selectionType = item.selectionType == undefined ? 'single' : item.selectionType;
    item.show = item.show == undefined ? true : !!item.show;
    item.required = item.required == undefined ? false : !!item.required;
    item.sortable = item.sortable == undefined ? false : !!item.sortable;
    item.sortWay = '';
    item.sortField = !item.sortField ? item.prop : item.sortField;
    item.showOverflowTooltip = item.showOverflowTooltip == undefined ? true : !!item.sortable;
    item.align = item.align == undefined ? 'left' : item.align;
    item.lastOne = length == index + 1;
  }

  // 深度克隆
  function deepClone(obj) {
    // 对常见的“非”值，直接返回原来值
    if ([null, undefined, NaN, false].includes(obj)) return obj;
    if (typeof obj !== "object" && typeof obj !== 'function') {
      //原始类型直接返回
      return obj;
    }
    var o = isArray(obj) ? [] : {};
    for (let i in obj) {
      if (obj.hasOwnProperty(i)) {
        o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
      }
    }
    return o;
  }

  function calcWidth($el, columns) {
    // 剩余宽度
    let resiWidth = $el.width() - 1;
    let tableTotalWidth = 0;
    // 没有宽度的项
    let noWidths = columns.filter(item => {
      if (item.show) {
        if (item.width) {
          tableTotalWidth += item.width;
          resiWidth -= item.width;
          return false;
        } else {
          return true;
        }
      }
      return true;
    });
    if (!noWidths.length) return;
    let everyWidth;
    let remainder;
    if (resiWidth <= 0) {
      everyWidth = 80;
    } else {
      everyWidth = parseInt(resiWidth / noWidths.length);
      if (everyWidth < 80) {
        everyWidth = 80;
        remainder = 0;
      } else {
        remainder = resiWidth % noWidths.length;
      }
    }
    noWidths.forEach((item, index) => {
      item.width = everyWidth;
      tableTotalWidth += everyWidth;
    })
    noWidths[0].width += remainder;
    tableTotalWidth += remainder;
    return tableTotalWidth;
  }

})(jQuery, Vue)
